package com.gopay.scheduler.job;

import com.gopay.common.user.dao.PersonIdentifyDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.scheduler.GopayBaseJob;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * Created by zhaojt on 2017/3/23.
 * 生产三期： 处理存量订单 结算金额字段
 */
public class DealSettleAmtJob  extends GopayBaseJob{

    @Autowired
    private PersonIdentifyDAO personIdentifyDAO;

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void doJobInternal() {

        SimpleDateFormat sdf  = new SimpleDateFormat(DateUtils.FILEDATE_PATTERM);

        //起始时间点  20150101
        Date startTime = null;
        Date endTime = DateUtils.strToDate("20150101",DateUtils.FILEDATE_PATTERM );

        Date over = new Date();

        long start = System.currentTimeMillis();

        Date _2015 = DateUtils.strToDate("20150101",DateUtils.FILEDATE_PATTERM );
        Date _2016 = DateUtils.strToDate("20160101",DateUtils.FILEDATE_PATTERM );
        Date _2017 = DateUtils.strToDate("20170101",DateUtils.FILEDATE_PATTERM );
        /**
         * 时间节点  ：
         * 2015年以前，一批
         * 2015--2016  一周一次
         * 2016--2017  一周一次
         * 2017 3月之后    一天
         */
        logger.info("开始执行结算金额处理任务...");

        logger.info("先处理不需要时间条件的交易 ：");

        try {
            deal02(); //冲正
        }catch (Exception e){
            logger.error("deal02 -- 冲正交易处理失败， 需重新处理 !" , e);
        }

        try {
            deal05(); //提现
        }catch (Exception e){
            logger.error("deal05 -- 提现交易处理失败， 需重新处理 !" , e);
        }

        logger.info("再处理带时间条件的交易 ：");

        while((startTime == null && endTime != null) || (startTime.getTime() < over.getTime())){

            String s = startTime == null ? null : sdf.format(startTime);
            String e = endTime == null ? null : sdf.format(endTime);

            logger.info("处理交易 时间入参 ： startTime = " + s + "-- endTime = " + e );

            try {
                deal01(s, e);
            }catch (Exception ex){
                logger.error("deal01 -- 处理失败， 需重新处理 !" , e);
            }


            try {
                deal04(s, e);
            }catch (Exception ex){
                logger.error("deal04 -- 处理失败， 需重新处理 !" , e);
            }

            //时间计算
            startTime = endTime;

            int circle = Calendar.DATE ;

            endTime = DateUtils.add(endTime, circle, 1);

        }

        logger.info("结算金额存量数据处理圆满结束! 耗时 ：" + (System.currentTimeMillis() - start) + "毫秒。");

    }


    /**
     * 处理：
     * 结算金额 等于 交易金额  的交易类型
     */
    public void deal01(String start, String end){
        logger.info("deal -- 结算金额 等于 交易金额  的交易类型");
        //交易码
        String intTxnCds = "('00700','00900','01200','01201','01203','01601','01602','02200'," +
                "'01603','01604','01605','01606','01607','01608','01609','01610','01611','01612','01613','01614','01615'," +
                "'00666','02004','02012','02016','02018','01809','01810','01811','01812'," +
                "'00601','00602','00603','00604','00605','01400','09800','09802','09803','01837','01808')";

        StringBuilder sql = new StringBuilder();
        sql.append(" update cps_gen_main_order t set t.settle_amt = t.mer_txn_amt ");
        sql.append(" where t.gopay_int_txn_cd in " + intTxnCds + " ");

        sql.append(timeSpan(start,end));

        doUpdate(sql.toString());
    }

    /**
     * 处理：
     * 结算金额 等于 原订单结算金额 的交易类型
     */
    public void deal02(){
        logger.info("deal -- 结算金额 等于 原订单结算金额 的交易类型");
        /**
         * 因 生产库 冲正订单就670多笔  所以一次执行
         */
        StringBuilder sql = new StringBuilder();
        sql.append(" update cps_gen_main_order t ");
        sql.append(" set t.settle_amt = ");
        sql.append(" ( select o.settle_amt from cps_gen_main_order o ");
        sql.append(" where t.relevance_gopay_order_id = o.gopay_order_id ");
        sql.append(" and t.gopay_int_txn_cd in ('09900', '09901') ) ");
        sql.append(" where t.gopay_int_txn_cd in ('09900', '09901') ");

        doUpdate(sql.toString());
    }


    /**
     * 处理：网关支付,充值
     */
    public void deal04(String start, String end){

        StringBuilder sql1 = new StringBuilder();
        sql1.append(" update cps_gen_main_order t set t.settle_amt = t.mer_txn_amt + t.order_real_fee_amt ");
        sql1.append(" where t.gopay_int_txn_cd in ('00100', '00500') ");
        sql1.append(" and t.order_fee_payer = '01' "); //付方
        sql1.append(timeSpan(start,end));

        StringBuilder sql2 = new StringBuilder();
        sql2.append(" update cps_gen_main_order t set t.settle_amt = t.mer_txn_amt");
        sql2.append(" where t.gopay_int_txn_cd in ('00100', '00500') ");
        sql2.append(" and t.order_fee_payer = '02' "); //收方
        sql2.append(timeSpan(start,end));

        //处理 网关支付,充值 付方付手续费的情况
        logger.info("deal -- 网关支付,充值  付方付手续费的情况");
        doUpdate(sql1.toString());

        //add by zhaojt 生产环境加sleep 减少数据库压力
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            logger.error("sleep", e);
        }

        //处理 网关支付,充值 收方付手续费的情况
        logger.info("deal -- 网关支付,充值  收方付手续费的情况");
        doUpdate(sql2.toString());

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            logger.error("sleep", e);
        }

    }

    /**
     * 处理：提现
     */
    public void deal05(){
        StringBuilder sql1 = new StringBuilder();
        sql1.append(" update cps_gen_main_order t set t.settle_amt = t.mer_txn_amt ");
        sql1.append(" where t.gopay_int_txn_cd = '00800' ");
        sql1.append(" and t.order_fee_payer = '01' "); //付方

        StringBuilder sql2 = new StringBuilder();
        sql2.append(" update cps_gen_main_order t set t.settle_amt = t.mer_txn_amt ");
        sql2.append(" where t.gopay_int_txn_cd = '00800' ");
        sql2.append(" and t.order_fee_payer = '02' "); //收方

        //处理 提现 付方付手续费的情况
        logger.info("deal -- 提现  付方付手续费的情况");
        doUpdate(sql1.toString());

        //处理 提现 收方付手续费的情况
        logger.info("deal -- 提现  收方付手续费的情况");
        doUpdate(sql2.toString());
    }


    /**
     * 时间条件
     * @param start
     * @param end
     * @return
     */
    private String timeSpan(String start, String end){
        StringBuilder sql = new StringBuilder();
        if(StringUtils.isNotBlank(start)) {
            sql.append(" and t.GOPAY_TXN_TM >= to_date('"+ start +"','yyyymmdd') ");
        }
        if(StringUtils.isNotBlank(end)) {
            sql.append(" and t.GOPAY_TXN_TM <= to_date('"+ end +"','yyyymmdd') ");
        }
        return sql.toString();
    }

    /**
     * 执行sql  更新
     * @param sql
     * @return
     */
    private int doUpdate(String sql){
        long s = System.currentTimeMillis();
        logger.info("执行更新sql开始： ");
        int i = personIdentifyDAO.updateBySql(sql.toString(), null);
        logger.info("执行更新完毕! 共更新了 " +  i +" 条! 单次耗时 ：" + (System.currentTimeMillis() - s));
        return i;
    }

}
